package cn.nexd.location.collector.core.collectors;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import cn.nexd.location.collector.NexdCollector;
import cn.nexd.location.collector.NexdCollectorConfig;
import cn.nexd.location.collector.bean.BluetoothCollectorResult;
import cn.nexd.location.collector.core.BluetoothCollector;
import cn.nexd.location.utils.threadpool.ThreadTaskObject;
import cn.nexd.location.utils.threadpool.core.ThreadPoolDelegate;

/**
 * 蓝牙状态:
 * int STATE_OFF        蓝牙已经关闭
 * int STATE_ON        蓝牙已经打开
 * int STATE_TURNING_OFF      蓝牙处于关闭过程中 ，关闭ing
 * int STATE_TURNING_ON        蓝牙处于打开过程中 ，打开ing
 * <p/>
 * 蓝牙扫描状态:
 * <p/>
 * int  SCAN_MODE_CONNECTABLE         表明该蓝牙可以扫描其他蓝牙设备
 * int  SCAN_MODE_CONNECTABLE_DISCOVERABLE  表明该蓝牙设备同时可以扫码其他蓝牙设备，并且可以被其他蓝牙设备扫描到。
 * int  SCAN_MODE_NONE ： 该蓝牙不能扫描以及被扫描。
 * <p/>
 * Created by codngfish on 15/10/19.
 */
final class BluetoothCollectorTask extends BluetoothCollector {


    private BluetoothAdapter bluetoothAdapter;
    private Context context;
    private NexdCollectorConfig collectorConfig;
    private BluetoothCollectorListener bluetoothCollectorListener;
    private BluetoothCollectorTaskHandler handler;
    //    private boolean collectorTaskStoped = false;
    private final BluetoothManager bluetoothManager;
    private BluetoothLeScanner bluetoothLeScanner;
    private BluetoothCollectorTaskLeScanCallback bluetoothCollectorTaskLeScanCallback;
    private BluetoothCollectorTaskScanCallback bluetoothCollectorTaskScanCallback;
    private BluetoothCollectorBroadcastReceiver bluetoothCollectorBroadcastReceiver;

    private long collectorStartTime = 0L;
    private List<BluetoothCollectorResult> bluetoothCollectorResults;

    private boolean isCollectorTaskStoped = false;

    public BluetoothCollectorTask(Context context, NexdCollectorConfig collectorConfig, BluetoothCollectorListener bluetoothCollectorListener) {
        super(context, collectorConfig, bluetoothCollectorListener);
        this.context = context;
        this.collectorConfig = collectorConfig;
        this.bluetoothCollectorListener = bluetoothCollectorListener;
        handler = new BluetoothCollectorTaskHandler();
        bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);

        bluetoothCollectorResults = new ArrayList<BluetoothCollectorResult>();
        Log.d("BluetoothCollectorTask", "BluetoothCollectorTask");
    }


    @Override
    public boolean initilazeCollector() {
        //如果具备蓝牙功能,则返回 BluetoothAdapter 实例,否则返回 Null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            bluetoothAdapter = bluetoothManager.getAdapter();
        } else {
            bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        }

        if (bluetoothAdapter == null) {
            if (bluetoothCollectorListener != null) {
                bluetoothCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGE_COLLECTOR_UNAVAILABLE);
            }
            return false;
        }

        if (bluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF || bluetoothAdapter.getState() == BluetoothAdapter.STATE_TURNING_OFF || bluetoothAdapter.getScanMode() == BluetoothAdapter.SCAN_MODE_NONE) {
            if (bluetoothCollectorListener != null) {
                bluetoothCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_STATE_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGG_COLLECTOR_STATE_UNAVAILABLE);
            }
            return false;
        }

        return true;
    }

    @Override
    public boolean startCollector() {
        Log.d("BluetoothCollectorTask", "startCollector");
        isCollectorTaskStoped = false;
        //        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
        //            // 2.3 ------- 4.2
        //            bluetoothCollectorBroadcastReceiver = new BluetoothCollectorBroadcastReceiver();
        //            context.registerReceiver(bluetoothCollectorBroadcastReceiver, new IntentFilter());
        //        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
        //            // 4.3     4.4      4.4W
        //            bluetoothCollectorTaskLeScanCallback = new BluetoothCollectorTaskLeScanCallback();
        //            //            bluetoothAdapter.startLeScan(bluetoothCollectorTaskLeScanCallback);
        //        } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        //            // 5.0 以上
        //            bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        //            bluetoothCollectorTaskScanCallback = new BluetoothCollectorTaskScanCallback();
        //            //            bluetoothLeScanner.startScan(bluetoothCollectorTaskScanCallback);
        //        }

        bluetoothCollectorTaskLeScanCallback = new BluetoothCollectorTaskLeScanCallback();


        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().addTask(new BluetoothCollectorTaskThread());

        return true;
    }

    @Override
    public boolean stopCollector() {
        Log.d("BluetoothCollectorTask", "stopCollector");
        //        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
        //            // 2.3 ------- 4.2
        //            if (context != null) {
        //                context.unregisterReceiver(bluetoothCollectorBroadcastReceiver);
        //            }
        //        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
        //            // 4.3     4.4
        //            if (bluetoothAdapter != null) {
        //                bluetoothAdapter.stopLeScan(bluetoothCollectorTaskLeScanCallback);
        //            }
        //            //            bluetoothAdapter.cancelDiscovery();
        //        } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        //            // 5.0 以上
        //            if (bluetoothAdapter != null && bluetoothCollectorTaskScanCallback != null) {
        //                bluetoothAdapter.getBluetoothLeScanner().stopScan(bluetoothCollectorTaskScanCallback);
        //            }
        //            //            bluetoothLeScanner.startScan(null);
        //        }

        if (bluetoothAdapter != null) {
            bluetoothAdapter.stopLeScan(bluetoothCollectorTaskLeScanCallback);
        }
        isCollectorTaskStoped = true;

        return true;
    }

    @Override
    public boolean destroyCollector() {
        Log.d("BluetoothCollectorTask", "destroyCollector");

        if (bluetoothCollectorListener != null) {
            bluetoothCollectorListener = null;
        }

        if (handler != null) {
            handler = null;
        }

        //        if (bluetoothAdapter != null) {
        //            bluetoothAdapter = null;
        //        }

        //        if (bluetoothLeScanner != null) {
        //            bluetoothLeScanner = null;
        //        }

        if (context != null) {
            context = null;
        }
        return true;
    }

    private static final int HANDLER_MESSAGE_BLUETOOTHADAPTER_NULL = 0x271a;
    private static final int HANDLER_MESSAGE_BLUETOOTH_STATE_DISABLED = 0x271b;
    private static final int HANDLER_MESSAGE_BLUETOOTH_STATE_ENABLING = 0x271c;


    private static final int HANDLER_MESSAGE_BLUETOOTH_SCAN_SUCCESS = 0x2724;

    private class BluetoothCollectorTaskThread extends ThreadTaskObject {


        @Override
        public void run() {

            if (isCollectorTaskStoped) {
                return;
            }
            if (bluetoothAdapter == null && handler != null) {
                handler.sendEmptyMessage(HANDLER_MESSAGE_BLUETOOTHADAPTER_NULL);
                return;
            }

            if (bluetoothAdapter.getState() != BluetoothAdapter.STATE_ON) {
                // 不可用
                switch (bluetoothAdapter.getState()) {
                    case BluetoothAdapter.STATE_OFF:
                        // 已经关闭
                    case BluetoothAdapter.STATE_TURNING_OFF:
                        //正在关闭
                        if (handler != null) {
                            handler.sendEmptyMessage(HANDLER_MESSAGE_BLUETOOTH_STATE_DISABLED);
                        }
                        return;
                    case BluetoothAdapter.STATE_TURNING_ON:
                        //正在打开
                        try {
                            Thread.sleep(collectorConfig.bluetoothCollectorRate);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        if (handler != null) {
                            handler.sendEmptyMessage(HANDLER_MESSAGE_BLUETOOTH_STATE_ENABLING);
                        }
                        return;
                }
            }


            //            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            //                // 2.3 ------- 4.2
            //                bluetoothAdapter.startDiscovery();
            //            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
            //                // 4.3     4.4      4.4W
            //                bluetoothAdapter.startLeScan(bluetoothCollectorTaskLeScanCallback);
            //            } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            //                // 5.0 以上
            //                bluetoothLeScanner.startScan(bluetoothCollectorTaskScanCallback);
            //            }
            bluetoothAdapter.startLeScan(bluetoothCollectorTaskLeScanCallback);


            collectorStartTime = System.currentTimeMillis();
            try {
                Thread.sleep(collectorConfig.bluetoothCollectorRate);
                // 停止采集
                //                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
                //                    // 2.3 ------- 4.2
                //                    bluetoothAdapter.cancelDiscovery();
                //                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
                //                    // 4.3     4.4
                //                    bluetoothAdapter.stopLeScan(bluetoothCollectorTaskLeScanCallback);
                //                } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                //                    // 5.0 以上
                //                    bluetoothLeScanner.stopScan(bluetoothCollectorTaskScanCallback);
                //                }

//                bluetoothAdapter.stopLeScan(bluetoothCollectorTaskLeScanCallback);
                if (handler != null) {
                    handler.sendEmptyMessage(HANDLER_MESSAGE_BLUETOOTH_SCAN_SUCCESS);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    private class BluetoothCollectorTaskHandler extends Handler {


        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case HANDLER_MESSAGE_BLUETOOTHADAPTER_NULL:
                    //BluetoothAdapter null
                    if (bluetoothCollectorListener != null) {
                        bluetoothCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGE_COLLECTOR_UNAVAILABLE);
                    }
                    Runtime.getRuntime().gc();
                    break;
                case HANDLER_MESSAGE_BLUETOOTH_STATE_DISABLED:
                    // 已经关闭或者正在关闭
                    if (bluetoothCollectorListener != null) {
                        bluetoothCollectorListener.onStop(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_STOP_TYPE_COLLECTOR_STATE_UNAVAILABLE, NexdCollector.COLLECTOR_TASK_STOP_MESSAGG_COLLECTOR_STATE_UNAVAILABLE);
                    }
                    break;

                case HANDLER_MESSAGE_BLUETOOTH_STATE_ENABLING:
                    if (bluetoothCollectorListener != null) {
                        bluetoothCollectorListener.onFailed(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_FAILED_TYPE_COLLECTOR_STATE_OPENNING, NexdCollector.COLLECTOR_TASK_FAILED_MESSAGG_COLLECTOR_STATE_OPENNING);
                    }
                    // 重启线程
                    if (!isCollectorTaskStoped) {
                        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().addTask(new BluetoothCollectorTaskThread());
                    }
                    break;
                case HANDLER_MESSAGE_BLUETOOTH_SCAN_SUCCESS:
                    //成功
                    //处理数据 数据堆到前台
                    if (!isCollectorTaskStoped) {
                        ThreadPoolDelegate.getThreadPoolDelegate().getThreadPoolManager().addTask(new BluetoothCollectorTaskThread());
                    }
                    Log.d("collectorResults", "########蓝牙数量:" + bluetoothCollectorResults.size());

                    // 此处处理一遍蓝牙数据然后回调前台


                    if (bluetoothCollectorResults.size() > 0) {
                        ArrayList<BluetoothCollectorResult> bluetoothCollectorResultArrayList = new ArrayList<BluetoothCollectorResult>();
                        bluetoothCollectorResultArrayList.addAll(BluetoothCollectorTask.this.bluetoothCollectorResults);
                        bluetoothCollectorListener.onSuccess(getTaskId(), System.currentTimeMillis(), bluetoothCollectorResultArrayList);
                        bluetoothCollectorResults.clear();
                    } else {
                        bluetoothCollectorListener.onFailed(getTaskId(), System.currentTimeMillis(), NexdCollector.COLLECTOR_TASK_FAILED_TYPE_RESULT_NULL, NexdCollector.COLLECTOR_TASK_FAILED_MESSAGE_RESULT_NULL);
                    }
                    break;
            }
        }
    }

    private class BluetoothCollectorBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                //扫描开始
            } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                //发现设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device != null) {
                    //                    collectorResults.add(device);
                    BluetoothCollectorResult bluetoothCollectorResult = new BluetoothCollectorResult();
                    bluetoothCollectorResult.setAddress(device.getAddress());
                    bluetoothCollectorResult.setName(device.getName());
                    bluetoothCollectorResult.setCollectorId(getTaskId());
                    bluetoothCollectorResult.setCollectorRate(collectorConfig.bluetoothCollectorRate);
                    bluetoothCollectorResult.setStartTime(collectorStartTime);
                    bluetoothCollectorResult.setTimestamp(0);
                    bluetoothCollectorResult.setRssi(intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI));
                    bluetoothCollectorResult.setEndTime(System.currentTimeMillis());
                    bluetoothCollectorResults.add(bluetoothCollectorResult);
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                //扫描结束
            }
        }
    }

    private static int anInt = 0;

    //5.0
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private class BluetoothCollectorTaskScanCallback extends ScanCallback {

        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothCollectorResult bluetoothCollectorResult = new BluetoothCollectorResult();
            bluetoothCollectorResult.setAddress(result.getDevice().getAddress());
            bluetoothCollectorResult.setName(result.getDevice().getName());
            bluetoothCollectorResult.setCollectorId(getTaskId());
            bluetoothCollectorResult.setCollectorRate(collectorConfig.bluetoothCollectorRate);
            bluetoothCollectorResult.setStartTime(collectorStartTime);
            bluetoothCollectorResult.setTimestamp(0);
            bluetoothCollectorResult.setRssi(result.getRssi());
            bluetoothCollectorResult.setEndTime(System.currentTimeMillis());
            bluetoothCollectorResults.add(bluetoothCollectorResult);

            ///////
            //            collectorResults.add(result.getDevice());
            //            anInt++;
            Log.d("BluetoothCollectorTask", "onScanResult" + "  " + result.getDevice().getAddress() + "        " + callbackType);
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
            Log.d("BluetoothCollectorTask", "onBatchScanResults" + "  " + results.size());
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            Log.d("BluetoothCollectorTask", "onScanFailed" + "  " + errorCode);
        }
    }

    private List<BluetoothDevice> collectorResults = new ArrayList<BluetoothDevice>();

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    private class BluetoothCollectorTaskLeScanCallback implements BluetoothAdapter.LeScanCallback {

        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            Log.d("BluetoothCollectorTask", "onLeScan" + "  " + device.getAddress());
            BluetoothCollectorResult bluetoothCollectorResult = new BluetoothCollectorResult();
            bluetoothCollectorResult.setAddress(device.getAddress());
            bluetoothCollectorResult.setName(device.getName());
            bluetoothCollectorResult.setCollectorId(getTaskId());
            bluetoothCollectorResult.setCollectorRate(collectorConfig.bluetoothCollectorRate);
            bluetoothCollectorResult.setStartTime(collectorStartTime);
            bluetoothCollectorResult.setTimestamp(0);
            //            device.getBluetoothClass().getm
            bluetoothCollectorResult.setRssi(rssi);
            bluetoothCollectorResult.setEndTime(System.currentTimeMillis());
            bluetoothCollectorResults.add(bluetoothCollectorResult);
        }
    }
}
